using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Text;
using System.Windows.Forms;

namespace PatternMaker
{
	public partial class Form1 : Form
	{
		private Bitmap _original;
		private PatternGenerator _patternGenerator;

		public Form1()
		{
			InitializeComponent();
		}


		public Bitmap Original
		{
			get { return _original; }
			set { _original = value; }
		}

		public PatternGenerator PatternGenerator
		{
			get { return _patternGenerator; }
			set
			{
				if (_patternGenerator != null)
				{
					_patternGenerator.Complete += new EventHandler(_patternGenerator_Complete);
					_patternGenerator.ExceptionOccurred += new EventHandler<ExceptionEventArgs>(_patternGenerator_ExceptionOccurred);
					_patternGenerator.ProgressChanged += new EventHandler<ProgressEventArgs>(_patternGenerator_ProgressChanged);
					_patternGenerator.Started += new EventHandler(_patternGenerator_Started);
				}
				_patternGenerator = value;
				if (_patternGenerator != null)
				{
					_patternGenerator.Complete += new EventHandler(_patternGenerator_Complete);
					_patternGenerator.ExceptionOccurred += new EventHandler<ExceptionEventArgs>(_patternGenerator_ExceptionOccurred);
					_patternGenerator.ProgressChanged += new EventHandler<ProgressEventArgs>(_patternGenerator_ProgressChanged);
					_patternGenerator.Started += new EventHandler(_patternGenerator_Started);
				}
			}
		}

		void _patternGenerator_Complete(object sender, EventArgs e)
		{
			try
			{
				VoidHandler del = delegate()
				{
					//btnCancel.Enabled = false;
					pbOriginalThumbnail.Image = Original;
					pbPattern.Image = PatternGenerator.Pattern;
					pbPatternThumbnail.Image = PatternGenerator.PatternThumbnail;
					pbColours.Image = PatternGenerator.ColourChart;
					gbColours.Text = PatternGenerator.ColourCodes.Count.ToString() + " colours";
					//btnCreatePattern.Enabled = true;
					//btnNextFile.Enabled = true;
					tcWizard.SelectedTab = tpPatternPreview;
				};
				if (InvokeRequired) Invoke(del);
				else del();
			}
			catch (Exception ex)
			{
				HandleException(ex);
			}
		}

		void _patternGenerator_ExceptionOccurred(object sender, ExceptionEventArgs e)
		{
			VoidHandler del = delegate()
			{
				MessageBox.Show(e.Exception.ToString());
			};
			if (InvokeRequired) Invoke(del);
			else del();
		}

		void _patternGenerator_ProgressChanged(object sender, ProgressEventArgs e)
		{
			try
			{
				VoidHandler del = delegate()
				{
					if (e.Progress < progressBar1.Minimum)
					{
						lblProgress.Text = progressBar1.Minimum.ToString() + "%";
						progressBar1.Value = progressBar1.Minimum;
					}
					else if (e.Progress > progressBar1.Maximum)
					{
						lblProgress.Text = progressBar1.Maximum.ToString() + "%";
						progressBar1.Value = progressBar1.Maximum;
					}
					else
					{
						lblProgress.Text = e.Progress.ToString() + "%";
						progressBar1.Value = e.Progress;
					}
				};
				if (InvokeRequired) Invoke(del);
				else del();
			}
			catch (Exception ex)
			{
				HandleException(ex);
			}
		}

		void _patternGenerator_Started(object sender, EventArgs e)
		{
			try
			{
				VoidHandler del = delegate()
				{
					lblProgress.Text = "0%";
					progressBar1.Value = 0;
				};
				if (InvokeRequired) Invoke(del);
				else del();
			}
			catch (Exception ex)
			{
				HandleException(ex);
			}
		}


		

		private void HandleException(Exception ex)
		{
			MessageBox.Show(ex.ToString(), Text, MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
		}


		private void RefreshFiles()
		{
			lstFiles.Items.Clear();
			if (Directory.Exists(txtPath.Text))
			{
				FilenameFilter filenameFilter = cboFilter.SelectedItem as FilenameFilter;
				foreach (string filter in filenameFilter.Filters)
				{
					foreach (string fullFilename in Directory.GetFiles(txtPath.Text, filter))
					{
						string filename = Path.GetFileName(fullFilename);
						if (!lstFiles.Items.Contains(filename)) lstFiles.Items.Add(filename);
					}
				}
			}
		}

		//private void RefreshOriginal()
		//{
		//  Bitmap griddedOriginal = (Bitmap)Original.Clone();
		//  griddedOriginal = PatternGenerator.ScaleImage(griddedOriginal, (int)ntxtOriginalScale.Value);
		//  //ApplyGrid(griddedOriginal);
		//  pbOriginalPreview.Image = griddedOriginal;
		//}
		
		private void Form1_Load(object sender, EventArgs e)
		{
			try
			{
				FilenameFilter picturesFilter = new FilenameFilter();
				picturesFilter.Name = "Picture Files (*.jpg,*.gif,*.png,*.bmp)";
				picturesFilter.Filters.Add("*.bmp");
				picturesFilter.Filters.Add("*.gif");
				picturesFilter.Filters.Add("*.jpg");
				picturesFilter.Filters.Add("*.png");
				cboFilter.Items.Add(picturesFilter);
				cboFilter.SelectedItem = picturesFilter;

				FilenameFilter allFilesFilter = new FilenameFilter();
				allFilesFilter.Name = "All Files (*.*)";
				allFilesFilter.Filters.Add("*.*");
				cboFilter.Items.Add(allFilesFilter);

				txtPath.Text = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures);
			}
			catch (Exception ex)
			{
				HandleException(ex);
			}
		}


		#region tpFile event handlers

		private void btnBrowsePath_Click(object sender, EventArgs e)
		{
			try
			{
				if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
				{
					txtPath.Text = folderBrowserDialog1.SelectedPath;
				}
			}
			catch (Exception ex)
			{
				HandleException(ex);
			}
		}

		private void btnClose_Click(object sender, EventArgs e)
		{
			try
			{
				Close();
			}
			catch (Exception ex)
			{
				HandleException(ex);
			}
		}

		private void btnNextFile_Click(object sender, EventArgs e)
		{
			try
			{
				//InitializeOriginalSettings();
				//RefreshOriginal();
				CrossStitchPatternGenerator cs = new CrossStitchPatternGenerator();
				PatternGenerator = cs;
				PatternGenerator.CellCountHorizontal = (int)ntxtCellCountHorizontal.Value;
				PatternGenerator.CellCountVertical = (int)ntxtCellCountVertical.Value;
				//PatternGenerator.CellHeight = Original.Height / (int)ntxtCellCountHorizontal.Value;
				//PatternGenerator.CellWidth = Original.Width / (int)ntxtCellCountVertical.Value;
				PatternGenerator.Original = Original;
				PatternGenerator.Scale = (int)ntxtOriginalScale.Value;
				PatternGenerator.Preview();
				pbOriginalPreview.Image = PatternGenerator.Pattern;
				tcWizard.SelectedTab = tpOriginalPreview;
			}
			catch (Exception ex)
			{
				HandleException(ex);
			}
		}

		private void cboFilter_SelectedIndexChanged(object sender, EventArgs e)
		{
			try
			{
				RefreshFiles();
			}
			catch (Exception ex)
			{
				HandleException(ex);
			}
		}

		private void lstFiles_SelectedIndexChanged(object sender, EventArgs e)
		{
			try
			{
				if (lstFiles.SelectedItem != null)
				{
					Original = new Bitmap(Path.Combine(txtPath.Text, (string)lstFiles.SelectedItem));
					pbLoadPreview.Image = Original;
					btnNextFile.Enabled = true;
				}
			}
			catch (Exception ex)
			{
				HandleException(ex);
			}
		}

		private void txtPath_TextChanged(object sender, EventArgs e)
		{
			try
			{
				RefreshFiles();
			}
			catch (Exception ex)
			{
				HandleException(ex);
			}
		}

		#endregion

		#region tpOriginal event handlers

		private void btnOriginalNext_Click(object sender, EventArgs e)
		{
			try
			{
				tcWizard.SelectedTab = tpGenerating;
				PatternGenerator.CellCountHorizontal = (int)ntxtCellCountHorizontal.Value;
				PatternGenerator.CellCountVertical = (int)ntxtCellCountVertical.Value;
				PatternGenerator.ColourTolerance = (int)ntxtColourTolerance.Value;
				PatternGenerator.Font = Font;
				PatternGenerator.Original = Original;
				PatternGenerator.Scale = (int)ntxtOriginalScale.Value;
				
				PatternGenerator.Begin();
			}
			catch (Exception ex)
			{
				HandleException(ex);
			}
		}

		private void btnOriginalPrevious_Click(object sender, EventArgs e)
		{
			try
			{
				tcWizard.SelectedTab = tpFile;
			}
			catch (Exception ex)
			{
				HandleException(ex);
			}
		}

		private void chkAdvancedSettings_CheckedChanged(object sender, EventArgs e)
		{
			try
			{
				lblColourTolerance.Visible = chkAdvancedSettings.Checked;
				ntxtColourTolerance.Visible = chkAdvancedSettings.Checked;
			}
			catch (Exception ex)
			{
				HandleException(ex);
			}
		}

		private void ntxtCellCountHorizontal_ValueChanged(object sender, EventArgs e)
		{
			try
			{
				PatternGenerator.CellCountHorizontal = (int)ntxtCellCountHorizontal.Value;
				PatternGenerator.Preview();
				pbOriginalPreview.Image = PatternGenerator.Pattern;
			}
			catch (Exception ex)
			{
				HandleException(ex);
			}
		}

		private void ntxtCellCountVertical_ValueChanged(object sender, EventArgs e)
		{
			try
			{
				PatternGenerator.CellCountVertical = (int)ntxtCellCountVertical.Value;
				PatternGenerator.Preview();
				pbOriginalPreview.Image = PatternGenerator.Pattern;
			}
			catch (Exception ex)
			{
				HandleException(ex);
			}
		}

		private void ntxtOriginalScale_ValueChanged(object sender, EventArgs e)
		{
			try
			{
				PatternGenerator.Scale = (int)ntxtOriginalScale.Value;
				PatternGenerator.Preview();
				pbOriginalPreview.Image = PatternGenerator.Pattern;
			}
			catch (Exception ex)
			{
				HandleException(ex);
			}
		}

		#endregion

		#region tpGenerating event handlers
		
		private void btnCancel_Click(object sender, EventArgs e)
		{
			try
			{
				PatternGenerator.Cancel();
				tcWizard.SelectedTab = tpOriginalPreview;
			}
			catch (Exception ex)
			{
				HandleException(ex);
			}
		}

		#endregion

		#region tpPattern event handlers

		private void btnPatternPrevious_Click(object sender, EventArgs e)
		{
			try
			{
				tcWizard.SelectedTab = tpOriginalPreview;
			}
			catch (Exception ex)
			{
				HandleException(ex);
			}
		}

		private void btnPatternRestart_Click(object sender, EventArgs e)
		{
			try
			{
				tcWizard.SelectedTab = tpFile;
			}
			catch (Exception ex)
			{
				HandleException(ex);
			}
		}

		private void btnSaveColours_Click(object sender, EventArgs e)
		{
			try
			{
				if (saveFileDialog1.ShowDialog() == DialogResult.OK)
				{
					pbColours.Image.Save(saveFileDialog1.FileName, ImageFormat.Jpeg);
				}
			}
			catch (Exception ex)
			{
				HandleException(ex);
			}
		}

		private void btnSavePattern_Click(object sender, EventArgs e)
		{
			try
			{
				if (saveFileDialog1.ShowDialog() == DialogResult.OK)
				{
					pbPattern.Image.Save(saveFileDialog1.FileName, ImageFormat.Jpeg);
				}
			}
			catch (Exception ex)
			{
				HandleException(ex);
			}
		}

		private void ntxtPatternScale_ValueChanged(object sender, EventArgs e)
		{
			try
			{
				PatternGenerator.Scale = (int)ntxtPatternScale.Value;
				tcWizard.SelectedTab = tpGenerating;
				PatternGenerator.Begin();
			}
			catch (Exception ex)
			{
				HandleException(ex);
			}
		}

		#endregion
	}

	public delegate void VoidHandler();
}